using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Administration;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using SlamCms.SharePoint.Core;
using Microsoft.SharePoint.ApplicationRuntime;

namespace SlamCms.SharePoint.Features
{
	[Guid("6b99d28d-20df-4a71-b399-3c91d1ef4744")]
	public class SlamCmsModuleFeatureReceiver : SPFeatureReceiver
	{
		private static string _owner = "SLAMCMSModule";
		private SPWebConfigModification[] _modifications = {
			new SPWebConfigModification() { 
				Name = "trustLevel[@name='WSS_Custom_SlamCMS']", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, 
				Path = "/configuration/system.web/securityPolicy", 
				Value = "<trustLevel name=\"WSS_Custom_SlamCMS\" policyFile=\"C:\\Program Files\\Common Files\\Microsoft Shared\\Web Server Extensions\\14\\CONFIG\\wss_custom_slamcmstrust.config\" />"},
			new SPWebConfigModification() { 
				Name = "level", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute, 
				Path = "/configuration/system.web/trust", 
				Value = "WSS_Custom_SlamCMS"},
			new SPWebConfigModification() { 
				Name = "add[@name='SlamCmsModule']", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, 
				Path = "/configuration/system.web/httpModules", 
				Value = "<add name=\"SlamCmsModule\" type=\"SlamCms.SharePoint.SlamCmsModule, SlamCms.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2fbc3f2db29fdc61\" />"},
			new SPWebConfigModification() { 
				Name = "add[@name='SlamCmsModule']", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, 
				Path = "/configuration/system.webServer/modules", 
				Value = "<add name=\"SlamCmsModule\" preCondition=\"integratedMode\" type=\"SlamCms.SharePoint.SlamCmsModule, SlamCms.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2fbc3f2db29fdc61\" /> "},
			new SPWebConfigModification() { 
				Name = "add[@name='ContainerDisposalModule']", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, 
				Path = "/configuration/system.web/httpModules", 
				Value = "<add name=\"ContainerDisposalModule\" type=\"Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web\" />"},
			new SPWebConfigModification() { 
				Name = "add[@name='ContainerDisposalModule']", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, 
				Path = "/configuration/system.webServer/modules", 
				Value = "<add name=\"ContainerDisposalModule\" preCondition=\"managedHandler\" type=\"Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web\" /> "},
			new SPWebConfigModification() { 
				Name = "add[@name='PropertyInjectionModule']", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, 
				Path = "/configuration/system.web/httpModules", 
				Value = "<add name=\"PropertyInjectionModule\" type=\"Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web\" />"},
			new SPWebConfigModification() { 
				Name = "add[@name='PropertyInjectionModule']", 
				Owner = _owner, 
				Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, 
				Path = "/configuration/system.webServer/modules", 
				Value = "<add name=\"PropertyInjectionModule\" preCondition=\"managedHandler\" type=\"Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web\" /> "}
		};

		public override void FeatureActivated(SPFeatureReceiverProperties properties)
		{
			SPWebApplication application = (SPWebApplication)properties.Feature.Parent;

			foreach (SPWebConfigModification modification in _modifications)
			{
				application.WebConfigModifications.Add(modification);
			}

			application.WebService.ApplyWebConfigModifications();
			application.Update();

			string slamCmsGlobalAsaxContent = "<%@ Assembly Name=\"Microsoft.SharePoint\"%><%@ Assembly Name=\"Autofac.Integration.Web\"%><%@ Application Language=\"C#\" Inherits=\"SlamCms.SharePoint.Core.SlamCmsApplication, SlamCms.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2fbc3f2db29fdc61\" %>";
			Enum.GetValues(typeof (SPUrlZone)).Cast<SPUrlZone>().ToList().ForEach(z => 
				{
					string globalAsaxPath = Path.Combine(application.GetIisSettingsWithFallback(z).Path.FullName, "global.asax");
					if(File.Exists(globalAsaxPath)) File.WriteAllText(globalAsaxPath, slamCmsGlobalAsaxContent);
				});
			
			Thread.Sleep(1000);
		}

		public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
		{
			SPWebApplication application = (SPWebApplication)properties.Feature.Parent;

			List<SPWebConfigModification> modificationsToRemove = new List<SPWebConfigModification>();
			foreach (SPWebConfigModification modification in application.WebConfigModifications)
			{
				if (modification.Owner == _owner)
				{
					modificationsToRemove.Add(modification);
				}
			}

			foreach (SPWebConfigModification modification in modificationsToRemove)
			{
				application.WebConfigModifications.Remove(modification);
			}

			application.WebService.ApplyWebConfigModifications();
			application.Update();

			string defaultGlobalAsaxContent = "<%@ Assembly Name=\"Microsoft.SharePoint\"%><%@ Application Language=\"C#\" Inherits=\"Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication\" %>";
			Enum.GetValues(typeof (SPUrlZone)).Cast<SPUrlZone>().ToList().ForEach(z => 
				{
					string globalAsaxPath = Path.Combine(application.GetIisSettingsWithFallback(z).Path.FullName, "global.asax");
					if (File.Exists(globalAsaxPath)) File.WriteAllText(globalAsaxPath, defaultGlobalAsaxContent);
				});
			Thread.Sleep(1000);
		}
	}
}
